package cn.skycity.auth.security.clientdetails;

import cn.skycity.admin.api.OAuthClientFeignClient;
import cn.skycity.admin.pojo.dto.RegisteredClientDTO;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.security.oauth2.core.AuthorizationGrantType;
import org.springframework.security.oauth2.core.ClientAuthenticationMethod;
import org.springframework.security.oauth2.server.authorization.client.RegisteredClient;
import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository;
import org.springframework.security.oauth2.server.authorization.settings.ClientSettings;
import org.springframework.security.oauth2.server.authorization.settings.OAuth2TokenFormat;
import org.springframework.security.oauth2.server.authorization.settings.TokenSettings;
import org.springframework.stereotype.Component;

import java.time.Duration;

@Slf4j
@Component
@Qualifier("registeredClientRepository")
public class ClientDetailsServiceImpl implements RegisteredClientRepository {
    @Resource
    private OAuthClientFeignClient oAuthClientFeignClient;

    @Override
    public void save(RegisteredClient registeredClient) {

    }

    @Override
    public RegisteredClient findById(String id) {
        RegisteredClientDTO result = oAuthClientFeignClient.getOAuthClientById(id);
        return wrap(result);
    }

    @Override
    public RegisteredClient findByClientId(String clientId) {
        RegisteredClientDTO result = oAuthClientFeignClient.getOAuthClientByClientId(clientId);
        return wrap(result);
    }

    /**
     * resolve return result
     * @param sysOauthClient
     * @return
     */
    public RegisteredClient wrap(RegisteredClientDTO sysOauthClient){
        RegisteredClient.Builder builder = RegisteredClient.withId(String.valueOf(sysOauthClient.getId()))
            .clientId(sysOauthClient.getClientId())
            .clientSecret(sysOauthClient.getClientSecret())
            .tokenSettings(TokenSettings.builder().accessTokenFormat(OAuth2TokenFormat.REFERENCE)
                    .accessTokenTimeToLive(Duration.ofHours(2))
                    .refreshTokenTimeToLive(Duration.ofDays(1))
                    .build())
            .clientSettings(ClientSettings.withSettings(sysOauthClient.getClientSettings()).build());

        sysOauthClient.getClientAuthenticationMethods().forEach(method->{
            builder.clientAuthenticationMethod(new ClientAuthenticationMethod(method));
        });
        builder.authorizationGrantTypes(grant->{
            sysOauthClient.getAuthorizationGrantTypes().forEach(type->grant.add(new AuthorizationGrantType(type)));
        });
        builder.redirectUris(consumer->{
            sysOauthClient.getRedirectUris().forEach(consumer::add);
        });
        builder.scopes(scope->{
            sysOauthClient.getScopes().forEach(scope::add);
        });

        return builder.build();
    }
}
